/**
 * Copyright (c) 2009 blurredVision
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
 * associated documentation files (the "Software"), to deal in the Software without restriction, 
 * including without limitation the rights to use, copy, modify, merge, publish, distribute, 
 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or 
 * substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT 
 * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT 
 * OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
#include "StdAfx.h"
#include "IModelKFAnimated.h"
#include "IModelBase.h"

namespace model {

IModelKFAnimated::IModelKFAnimated(void)
:	m_iFPS(15),	// Default is 15 frame per second
	m_iMaxFrame(0),
	m_dCurrentFrame(1),
	m_iStartFrame(1),
	m_iEndFrame(1),
	m_bLoop(false),
	m_bStarted(false)
{
}

IModelKFAnimated::~IModelKFAnimated(void)
{
}

bool IModelKFAnimated::loadKeyFrameData(FILE *file, IModelBase *base)
{
	// Try to read info for every mesh
	for (unsigned int i=0; i<base->getNumMeshes(); ++i) {
		KeyFrameInfo kfInfo;
		// Read the number of frames
		fread(&kfInfo.numFrames, sizeof(int), 1, file);
		if (kfInfo.numFrames != 0) {
			for (int j=0; j<kfInfo.numFrames; ++j) {
				// Read the frame IDX and matrix
				KeyFrame kf;
				fread(&kf.frame, sizeof(int), 1, file);
				// Increase the maximum keyframe, if this frame is greater
				if (m_iMaxFrame < kf.frame)
					m_iMaxFrame = kf.frame;
				// Read the matrix
				fread(&kf.matrix[0], sizeof(float), 16, file);
				kfInfo.frames.push_back(kf);
			}
		}
		dynamic_cast<model::IMesh*>( base->getChild(i) )->setKeyFrameInfo( kfInfo);
	}
	return true;
}

bool IModelKFAnimated::updateKeyFrames(double dt)
{
	if (!m_bStarted) return false;
	// update the frame time 
	m_dCurrentFrame += dt * m_iFPS;
	if (m_dCurrentFrame > m_iEndFrame+1) {
		// If looped, jump to first frame
		if (m_bLoop)
			m_dCurrentFrame -= (m_iEndFrame-m_iStartFrame+1);
		else
			m_bStarted = false;
	}
	return true;
}

void IModelKFAnimated::setAnimationSpeed(int framesPerSecond)
{
	m_iFPS = framesPerSecond;
}

const int& IModelKFAnimated::getAnimationSpeed() const
{
	return m_iFPS;
}

void IModelKFAnimated::play(int startFrame, int endFrame, bool loop)
{
	if (startFrame < 1) startFrame = 1;
	if (endFrame > m_iMaxFrame) endFrame = m_iMaxFrame;
	m_iStartFrame = startFrame;
	m_dCurrentFrame = static_cast<double>( m_iStartFrame);
	m_iEndFrame = endFrame;
	m_bLoop = loop;
	m_bStarted = true;
}

void IModelKFAnimated::playAll(bool loop)
{
	play(0, m_iMaxFrame, loop);
}

void IModelKFAnimated::gotoAndStop(int framenum)
{
}

int IModelKFAnimated::getFrameCount() const
{
	return m_iMaxFrame - 1;
}

const int IModelKFAnimated::getCurrentFrame() const
{
	return static_cast<int>(m_dCurrentFrame);
}

} // namespace
